package com.molichuxing.gateway.api.services.impl;

import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import com.molichuxing.gateway.bff.car.entity.request.create.MaintenanceConfigCreateVo;
import com.molichuxing.gateway.bff.car.entity.request.modify.*;
import com.molichuxing.gateway.bff.car.entity.response.*;
import com.molichuxing.gateway.bff.car.services.*;
import com.molichuxing.gateway.bff.dealer.entity.response.DealerListVo;
import com.molichuxing.gateway.property.DealerStatusEnum;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.result.ResponseCodeEnum;
import com.molichuxing.framework.result.ResponseResult;
import com.molichuxing.framework.utils.DateUtil;
import com.molichuxing.framework.utils.DownloadFileUtil;
import com.molichuxing.framework.utils.ObjectCastUtil;
import com.molichuxing.framework.utils.ValidateUtil;
import com.molichuxing.gateway.api.config.OptionalLogConfig;
import com.molichuxing.gateway.api.services.VehicleApiService;
import com.molichuxing.gateway.bff.car.convertor.Convert;
import com.molichuxing.gateway.bff.car.entity.request.create.AccidentExamineCreateVo;
import com.molichuxing.gateway.bff.car.entity.request.create.CarLicencePlateCreateVo;
import com.molichuxing.gateway.bff.car.entity.request.create.MaintenanceLogCreateVo;
import com.molichuxing.gateway.property.OSSFileFolderEnum;
import com.molichuxing.gateway.utils.ContantsUtil;
import com.molichuxing.gateway.utils.PoiExcelUtil;
import com.molichuxing.gateway.utils.TokenUtil;
import com.molichuxing.gateway.utils.entity.UserEntity;
import com.molichuxing.services.infrastructure.service.CarDetailService;
import com.molichuxing.services.property.CarInsuranceTypeEnum;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * 车辆相关接口
 * @author xuelin yi
 */
@Api(tags = "车辆相关接口")
@RestController
@RequestMapping(value = "/vehicle")
public class VehicleApiServiceImpl extends RootApiService implements VehicleApiService {
	private static final Logger logger = LoggerFactory.getLogger(VehicleApiServiceImpl.class);

	@Resource
	private CarCheckBffService carCheckBffService;

    @Resource
    private ViolationBffService violationBffService;

	@Resource
	private LicencePlateBffService licencePlateBffService;

	@Resource
	private YearlyInspectBffService yearlyInspectBffService;

	@Resource
	private InsuranceBffService insuranceBffService;

	@Resource
	private CarBffService carBffService;

	@Resource
	private AccidentBffService accidentBffService;

	@Resource
	private MaintenanceBffService maintenanceBffService;

	@Resource
	private TokenUtil tokenUtil;

	@Resource
	private ThreadPoolTaskExecutor taskExecutor;


	@Resource
	private CarDetailService carDetailService;
	
	@Resource
	private CarDownloadBffService carDownloadBffService;

	@Value("${zip.file.path}")
	private String zipFilePath;

	@Resource
	private CarFenceExceptionBffService carFenceExceptionBffService;
	@Resource
	private IVehicleMonitorBffService iVehicleMonitorBffService;

	@Resource
	private WarnConfigBffService warnConfigBffService;
	/**
	 * 获取商品列表信息
	 * @param
	 * @return
	 */
	@Override
	@ApiOperation(value = "获取新车检验列表信息")
	@ApiImplicitParams({
			    @ApiImplicitParam(name = "licencePlate", value = "车牌号", required = false, dataType = "String"),
			    @ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			    @ApiImplicitParam(name = "carType", value = "车辆类型", required = false, dataType = "Integer"),
					@ApiImplicitParam(name = "status", value = "检验状态", required = false, dataType = "Integer"),
					@ApiImplicitParam(name = "startCheckTime", value = "开始时间", required = false, dataType = "String"),
					@ApiImplicitParam(name = "endCheckTime", value = "结束时间", required = false, dataType = "String"),
			    @ApiImplicitParam(name = "pageNum", value = "页码", required = true, dataType = "Integer"),
			    @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "Integer")

	})
	@GetMapping(value = "/check/list")
	public ResponseResult<Paged<CarCheckVo>> getCarCheckList(@RequestParam Map<String, Object> selectParams){
		ResponseResult<Paged<CarCheckVo>> result = new ResponseResult<>();
		try {
			return result.success(carCheckBffService.getCarCheckList(selectParams));
		} catch (Exception e) {
			logger.error("[新车检验]获取新车检验列表信息异常", e);
			result.error("获取新车检验列表信息异常");
		}
		return result;
	}

	/**
	 * 	 * 获取检验详情基础信息
	 * 	 * @param
	 * 	 * @return
	 */
	@Override
	@ApiOperation(value = "获取检验详情基础信息")
	@ApiImplicitParam(name = "checkId", value = "检验id", required = true, dataType = "Integer")
	@GetMapping(value = "/check/base")
	public ResponseResult<CarBasicVo> getCheckBasicInfo(@RequestParam Integer checkId) {
		ResponseResult<CarBasicVo> result = new ResponseResult<>();
		try {
			return result.success(carCheckBffService.getCheckBasicInfo(checkId));
		} catch (Exception e) {
			logger.error("[getCheckBasicInfo]获取检验详情基础信息异常", e);
			result.error("获取检验详情基础信息异常");
		}
		return result;
	}

	/**
	 * 根据检验id 获取检验信息
	 * @param
	 * @return
	 */
	@Override
	@ApiOperation(value = "根据检验id获取新车检验信息")
	@ApiImplicitParam(name = "checkId", value = "检验id", required = true, dataType = "Integer")
	@GetMapping(value = "/check/checkdetail")
	public ResponseResult<CheckVo> getCheckNewInfo(@RequestParam Integer checkId) {
		ResponseResult<CheckVo> result = new ResponseResult<>();
		try {
			return result.success(carCheckBffService.getCheckNewInfo(checkId));
		} catch (Exception e) {
			logger.error("[getCheckNewInfo]根据检验id获取新车检验信息异常", e);
			result.error("根据检验id获取新车检验信息异常");
		}
		return result;
	}



	/**
	 * 根据检验id 获取检验信息
	 * @param
	 * @return
	 */
	@Override
	@ApiOperation(value = "根据检验id获取PDI 检验信息")
	@ApiImplicitParam(name = "checkId", value = "检验id", required = true, dataType = "Integer")
	@GetMapping(value = "/check/pdicheckdetail")
	public ResponseResult<PdiCheckVo> getPdiCheckNewInfo(@RequestParam Integer checkId) {
		ResponseResult<PdiCheckVo> result = new ResponseResult<>();
		try {
			return result.success(carCheckBffService.getPdiCheckNewInfo(checkId));
		} catch (Exception e) {
			logger.error("[getPdiCheckNewInfo]根据检验id获取PDI 检验信息异常", e);
			result.error("根据检验id获取PDI 检验信息");
		}
		return result;
	}


	@Override
	@ApiOperation(value = "根据车辆检验id 获取检验图片信息")
	@ApiImplicitParam(name = "checkId", value = "检验id", required = true, dataType = "Integer")
	@GetMapping(value = "/checkimage/list")
	public ResponseResult<CheckImageVo> getCheckImageInfo(@RequestParam Integer checkId) {
		ResponseResult<CheckImageVo> result = new ResponseResult<>();
		try {
			return result.success(carCheckBffService.getCheckImageInfo(checkId));
		} catch (Exception e) {
			logger.error("[getCheckImageInfo]根据车辆检验id 获取检验图片信息异常", e);
			result.error("根据车辆检验id 获取检验图片信息异常");
		}
		return result;
	}

	/**
	 *根据检验id 获取车辆整备信息
	 * @param
	 * @return
	 */
	@Override
	@ApiOperation(value = "根据检验id获取车辆整备信息")
	@ApiImplicitParam(name = "checkId", value = "检验id", required = true, dataType = "Integer")
	@GetMapping(value = "/check/preparationinfo")
	public ResponseResult<CheckPreparationVo> getCheckPreparationInfo(@RequestParam Integer checkId) {
		ResponseResult<CheckPreparationVo> result = new ResponseResult<>();
		try {
			return result.success(carCheckBffService.getCheckPreparationInfo(checkId));
		} catch (Exception e) {
			logger.error("[getPdiCheckNewInfo]根据检验id获取车辆整备信息异常", e);
			result.error("根据检验id获取车辆整备信息异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "新车检验验车接口")
	@PostMapping(value = "/check/checkcar")
	@OptionalLogConfig(methods="新车检验验车")
	public ResponseResult<Boolean> checkCar(@RequestBody CheckModifyVo checkModifyVo) throws Exception {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			return result.success(carCheckBffService.checkCar(Convert.toCheckModifyDto(checkModifyVo)));
		} catch (Exception e) {
			logger.error("[checkCar]新车检验验车接口异常", e);
			result.error("新车检验验车接口异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "获取pdi检验列表信息")
	@ApiImplicitParams({
					@ApiImplicitParam(name = "licencePlate", value = "车牌号", required = false, dataType = "String"),
					@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
					@ApiImplicitParam(name = "orderCode", value = "订单号", required = false, dataType = "Long"),
					@ApiImplicitParam(name = "status", value = "检验状态", required = false, dataType = "Integer"),
					@ApiImplicitParam(name = "returnStoreId", value = "还车门店", required = false, dataType = "Integer"),
					@ApiImplicitParam(name = "pageNum", value = "页码", required = true, dataType = "Integer"),
					@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "Integer")

	})
	@GetMapping(value = "/check/pdilist")
	public ResponseResult<Paged<CarCheckVo>> getPdiCarCheck(@RequestParam  Map<String, Object> selectParams) {
		ResponseResult<Paged<CarCheckVo>> result = new ResponseResult<>();
		try {
			return result.success(carCheckBffService.getPdiCarCheck(selectParams));
		} catch (Exception e) {
			logger.error("[PDI检验]获取pdi检验列表信息异常", e);
			result.error("获取pdi检验列表信息异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "PDI检验验车接口")
	@PostMapping(value = "/check/pdicheckcar")
	@OptionalLogConfig(methods="PDI检验验车")
	public ResponseResult<Boolean> pdiCheckCar(@RequestBody PdiCheckModifyVo pdiCheckModifyVo) throws Exception {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			return result.success(carCheckBffService.pdiCheckCar(Convert.toPdiCheckModifyDto(pdiCheckModifyVo)));
		} catch (BizException e) {
			logger.error("[pdicheckcar]pdi检验异常异常:", e);
			result.error(e.getExceptionCode(), e.getMessage());
		} catch (Exception e) {
			logger.error("[pdicheckcar]PDI检验验验车接口异常", e);
			result.error("PDI检验验验车接口异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "PDI检验争议处理接口")
	@PostMapping(value = "/check/discusspdicheck")
	public ResponseResult<Boolean> discussPdiCheck(@RequestBody DisPdiCheckModifyVo disPdiCheckModifyVo) throws Exception {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			return result.success(carCheckBffService.discussPdiCheck(Convert.toDisPdiCheckModifyDto(disPdiCheckModifyVo)));
		} catch (Exception e) {
			logger.error("[discussPdiCheck]PDI检验争议处理接口异常", e);
			result.error("PDI检验争议处理接口异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "获取车牌详细信息")
	@ApiImplicitParam(name = "carId", value = "车辆id", required = true, dataType = "Integer")
	@GetMapping(value = "/licence/detail")
	public ResponseResult<CarLicencePlateDetailVo> getLicencePlate(@RequestParam int carId) throws Exception {
		ResponseResult<CarLicencePlateDetailVo> result = new ResponseResult<>();
		try {
			return result.success(licencePlateBffService.getLicencePlate(carId));
		} catch (Exception e) {
			logger.error("[licence/detail]获取车牌详细信息接口异常", e);
			result.error("获取车牌详细信息接口异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "新增车牌信息列表")
	@PostMapping(value = "/licence/create")
	@OptionalLogConfig(methods="新增车牌")
	public ResponseResult<Integer> createLicencePlate(@RequestBody CarLicencePlateCreateVo createVo) throws Exception {
		ResponseResult<Integer> result = new ResponseResult<>();
		try {
			return result.success(licencePlateBffService.createLicencePlate(createVo));
		} catch (BizException e) {
			logger.error("[createLicencePlate]新增车牌信息列表异常:", e);
			result.error(e.getExceptionCode(), e.getMessage());
		} catch (Exception e) {
			logger.error("[licence/create]新增车牌信息列表接口异常", e);
			result.error("新增车牌信息列表接口异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "编辑车牌信息列表")
	@PostMapping(value = "/licence/modify")
	@OptionalLogConfig(methods="编辑车牌")
	public ResponseResult<Integer> modifyLicencePlate(@RequestBody CarLicencePlateModifyVo modifyVo) throws Exception {
		ResponseResult<Integer> result = new ResponseResult<>();
		try {
			return result.success(licencePlateBffService.modifyLicencePlate(modifyVo));
		} catch (BizException e) {
            logger.error("[modifyLicencePlate]编辑车牌信息列表异常:", e);
            result.error(e.getExceptionCode(), e.getMessage());
        }  catch (Exception e) {
			logger.error("[licence/modify]编辑车牌信息列表接口异常", e);
			result.error("编辑车牌信息列表接口异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "获取年检列表信息")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "yearlyInspectStatus", value = "年检状态NORMAL(0, 即将过期,1, 过期);", required = true, dataType = "String"),
			@ApiImplicitParam(name = "licencePlate", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "addressType", value = "车辆位置类型（1：中转库，2：门店）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "addressId", value = "车辆位置Id", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "inspectStartDate", value = "年检开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "inspectEndDate", value = "年检结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "handleStatus", value = "办理状态（0：未办理，1：办理中，2：已退回，3：年检已更新）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "pageNum", value = "页码", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "sortName", value = "排序字段", required = true, dataType = "String"),
			@ApiImplicitParam(name = "sortWay", value = "排序方式", required = true, dataType = "String")
	})
	@GetMapping(value = "/yearly/list")
	public ResponseResult<Paged<CarYearlyInspectVo>> getYearlyInspect(@RequestParam int yearlyInspectStatus,
			@RequestParam(name = "licencePlate", required = false)String licencePlate,
			@RequestParam(name = "vin", required = false) String vin,
			@RequestParam(name = "addressType", required = false) Integer addressType,
			@RequestParam(name = "addressId", required = false) Integer addressId,
			@RequestParam(name = "inspectStartDate", required = false) String inspectStartDate,
			@RequestParam(name = "inspectEndDate", required = false) String inspectEndDate,
			@RequestParam(name = "handleStatus", required = false) Integer handleStatus,
			@RequestParam(name = "sortName", required = false) String sortName,
			@RequestParam(name = "sortWay", required = false) String sortWay,
			@RequestParam(name = "pageNum", required = true) Integer pageNum,
			 @RequestParam(name = "pageSize", required = true) Integer pageSize) {
		ResponseResult<Paged<CarYearlyInspectVo>> result = new ResponseResult<>();
		try {
			return result.success(yearlyInspectBffService.getYearlyInspect(yearlyInspectStatus,licencePlate,vin, addressType,addressId, inspectStartDate, inspectEndDate,handleStatus,sortName, sortWay, pageNum,pageSize));
		} catch (Exception e) {
			logger.error("[yearly/detail]获取年检详细信息接口异常", e);
			result.error("获取年检详细信息接口异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "获取年检详细信息")
	@ApiImplicitParam(name = "carId", value = "车辆id", required = true, dataType = "Integer")
	@GetMapping(value = "/yearly/detail")
	public ResponseResult<YearlyInspectionVo> getYearlyInspectionByCarId(@RequestParam Integer carId) {
		ResponseResult<YearlyInspectionVo> result = new ResponseResult<>();
		try {
			return result.success(yearlyInspectBffService.getYearlyInspectionByCarId(carId));
		} catch (Exception e) {
			logger.error("[yearly/detail]获取年检详细信息接口异常", e);
			result.error("获取年检详细信息接口异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "编辑年检信息列表")
	@PostMapping(value = "/yearly/modify")
	@OptionalLogConfig(methods="编辑年检")
	public ResponseResult<Boolean> modifyYearlyInspection(@RequestBody @Valid YearlyInspectionModifyVo modifyDto, BindingResult bindingResult) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			return result.success(yearlyInspectBffService.modifyYearlyInspection(modifyDto));
		} catch (BizException e) {
			logger.error("[yearly/modify]编辑年检信息列表接口异常", e);
			result.error(e.getExceptionCode(), e.getMessage());
		} catch (Exception e) {
			logger.error("[yearly/modify]编辑年检信息列表接口异常", e);
			result.error("编辑年检信息列表接口异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "年检记录")
	@ApiImplicitParam(name = "carId", value = "车辆id", required = true, dataType = "Integer")
	@GetMapping(value = "/yearly/log/list")
	public ResponseResult<List<YearlyInspectionLogVo>> getYearlyInspectionLog(Integer carId) {
		ResponseResult<List<YearlyInspectionLogVo>> result = new ResponseResult<>();
		try {
			return result.success(yearlyInspectBffService.getYearlyInspectionLog(carId));
		} catch (BizException e) {
			logger.error("[/yearly/log/list]年检记录接口异常", e);
			result.error(e.getExceptionCode(), e.getMessage());
		} catch (Exception e) {
			logger.error("[/yearly/log/list]年检记录接口异常", e);
			result.error("年检记录接口异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "获取交强险信息列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "licencePlate", value = "车牌", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "type", value = "保险类别：1-交强险，2-商业险", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "code", value = "保单号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "status", value = "1:在保，2：过保保单,3:未生效保单 ", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "insuranceCompanyId", value = "保险公司ID", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "insureStartTime", value = "投保开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "insureEndTime", value = "投保结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "beginStartTime", value = "起保开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "beginEndTime", value = "起保结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endStartTime", value = "终保开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endEndTime", value = "终保结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "sortName", value = "排序字段", required = false, dataType = "String"),
			@ApiImplicitParam(name = "sortWay", value = "排序方式 asc:正序，desc:倒叙", required = false, dataType = "String"),
			@ApiImplicitParam(name = "pageNum", value = "页码", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "Integer")
	})
	@GetMapping(value = "/compulsory/insurance/list")
	public ResponseResult<Paged<CarInsuranceVo>> getCompulsoryInsurancePage(@RequestParam Map<String, Object> mapParam, @RequestParam Integer pageNum, @RequestParam Integer pageSize) {
		ResponseResult<Paged<CarInsuranceVo>> result = new ResponseResult<>();
		try {
			return result.success(insuranceBffService.getInsurancePage(mapParam, pageNum, pageSize));
		} catch (Exception e) {
			logger.error("[yearly/modify]获取交强险商业险信息列表接口异常", e);
			result.error("获取交强险商业险信息列表接口异常");
		}
		return result;
	}


	@Override
	@ApiOperation(value = "获取交强险信息列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "licencePlate", value = "车牌", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "type", value = "保险类别：1-交强险，2-商业险", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "code", value = "保单号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "status", value = "1:在保，2：过保保单,3:未生效保单 ", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "insuranceCompanyId", value = "保险公司ID", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "insureStartTime", value = "投保开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "insureEndTime", value = "投保结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "beginStartTime", value = "起保开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "beginEndTime", value = "起保结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endStartTime", value = "终保开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endEndTime", value = "终保结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "sortName", value = "排序字段", required = false, dataType = "String"),
			@ApiImplicitParam(name = "sortWay", value = "排序方式 asc:正序，desc:倒叙", required = false, dataType = "String"),
			@ApiImplicitParam(name = "pageNum", value = "页码", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "Integer")
	})
	@GetMapping(value = "/commercial/insurance/list")
	public ResponseResult<Paged<CarInsuranceVo>> getCommercialInsurancePage(@RequestParam Map<String, Object> mapParam, @RequestParam Integer pageNum, @RequestParam Integer pageSize) {
		ResponseResult<Paged<CarInsuranceVo>> result = new ResponseResult<>();
		try {
			return result.success(insuranceBffService.getInsurancePage(mapParam, pageNum, pageSize));
		} catch (Exception e) {
			logger.error("[yearly/modify]获取交强险商业险信息列表接口异常", e);
			result.error("获取交强险商业险信息列表接口异常");
		}
		return result;
	}



	@Override
	@ApiOperation(value = "获取保险详细信息")
	@ApiImplicitParam(name = "insuranceId", value = "保险id", required = true, dataType = "Integer")
	@GetMapping(value = "/insurance/detail")
	public ResponseResult<CarInsuranceDetailVo> getInsuranceById(@RequestParam int insuranceId) {
		ResponseResult<CarInsuranceDetailVo> result = new ResponseResult<>();
		try {
			return result.success(insuranceBffService.getInsuranceById(insuranceId));
		} catch (Exception e) {
			logger.error("[insurance/detail]获取保险详细信息接口异常", e);
			result.error("获取保险详细信息接口异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "根据交强险ID修改交强险信息")
	@PostMapping(value = "/insurance/compulsory/modify")
	public ResponseResult<Boolean> modifyCompulsoryInsurance(@RequestBody CarCompulsoryInsuranceModifyVo modifyDto) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			return result.success(insuranceBffService.modifyCompulsoryInsurance(modifyDto));
		} catch (Exception e) {
			logger.error("[insurance/compulsory/modify]根据交强险ID修改交强险信息异常", e);
			result.error("根据交强险ID修改交强险信息异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "根据商业险ID修改商业险险信息")
	@PostMapping(value = "/insurance/commercial/modify")
	public ResponseResult<Boolean> modifyCommercialInsurance(@RequestBody CarCommercialInsuranceModifyVo modifyDto) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			return result.success(insuranceBffService.modifyCommercialInsurance(modifyDto));
		} catch (Exception e) {
			logger.error("[insurance/commercial/modify]根据交强险ID修改商业险险信息异常", e);
			result.error("根据交强险ID修改商业险险信息异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "获取车辆信息列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "licencePlate", value = "车牌", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vehicleId", value = "车型Id", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "purchaseStartDate", value = "采购开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "purchaseEndDate", value = "采购结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "stockId", value = "仓库id", required = false, dataType = "Integer"),
            @ApiImplicitParam(name = "stockType", value = "仓库类型(1:中转库，2：门店)", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "vehicleType", value = "车辆类型（0：新车，1：二手车）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "plateStatus", value = "上牌状态：0：全部，1：未上牌，2：已上牌", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "status", value = "空：全部， 1：未入网，2：已入网，3：在库，4：在店，5：租赁，6：企业租赁，7：出售，8：空闲", required = false, dataType = "Integer"),
            @ApiImplicitParam(name = "vehicleStatus", value = "空：全部， 0：待出租，1：已出租，2：不可租", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "sortName", value = "排序字段", required = false, dataType = "String"),
			@ApiImplicitParam(name = "sortWay", value = "排序方式 asc:正序，desc:倒叙", required = false, dataType = "String"),
			@ApiImplicitParam(name = "pageNum", value = "页码", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "vehicleLockStatus", value = "0：全部， 1：是， 2：否", dataType = "Integer"),
			@ApiImplicitParam(name = "businessType", value = "空：全部,1,专属里程 2,订阅服务", dataType = "Integer"),
	})
	@GetMapping(value = "/cars/list")
	public ResponseResult<Paged<CarVo>> getCarList(@RequestParam Map<String, Object> selectParams, @RequestParam(name = "pageNum") Integer pageNum, @RequestParam(name = "pageSize") Integer pageSize) {
		ResponseResult<Paged<CarVo>> result = new ResponseResult<>();
		try {
			return result.success(carBffService.getCarList(selectParams, pageNum, pageSize));
		} catch (Exception e) {
			logger.error("[cars/list]获取车辆信息列表信息异常", e);
			result.error("获取车辆信息列表信息异常");
		}
		return result;
	}



	@Override
	@ApiOperation(value = "获取车辆信息列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "licencePlate", value = "车牌", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vehicleId", value = "车型Id", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "purchaseStartDate", value = "采购开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "purchaseEndDate", value = "采购结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "stockId", value = "仓库id", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "stockType", value = "仓库类型(1:中转库，2：门店)", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "vehicleType", value = "车辆类型（0：新车，1：二手车）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "plateStatus", value = "上牌状态：0：全部，1：未上牌，2：已上牌", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "status", value = "空：全部， 1：未入网，2：已入网，3：在库车辆，4：在店车辆，5：业务中，6：非业务", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "vehicleStatus", value = "空：全部， 0：待出租，1：已出租，2：不可租", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "sortName", value = "排序字段", required = false, dataType = "String"),
			@ApiImplicitParam(name = "sortWay", value = "排序方式 asc:正序，desc:倒叙", required = false, dataType = "String"),
			@ApiImplicitParam(name = "pageNum", value = "页码", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "Integer")

	})
	@GetMapping(value = "/cars/plate/list")
	public ResponseResult<Paged<CarVo>> getCarPlateList(@RequestParam Map<String, Object> selectParams, @RequestParam(name = "pageNum") Integer pageNum, @RequestParam(name = "pageSize") Integer pageSize) {
		ResponseResult<Paged<CarVo>> result = new ResponseResult<>();
		try {
			return result.success(carBffService.getCarList(selectParams, pageNum, pageSize));
		} catch (Exception e) {
			logger.error("[cars/list]获取车辆信息列表信息异常", e);
			result.error("获取车辆信息列表信息异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "获取车辆轨迹的时间范围")
	@ApiImplicitParam(name = "vin", value = "车架号", required = true, dataType = "String")
	@GetMapping(value = "/trajectory/time")
	public ResponseResult<List<String>> getTrajectoryTime(@RequestParam String vin) {
		ResponseResult<List<String>> result = new ResponseResult<>();
		try {
			return carBffService.getTrajectoryTime(vin);
		} catch (Exception e) {
			logger.error("[getTrajectoryTime]获取车辆轨迹的时间范围", e);
			result.error("获取车辆轨迹的时间范围");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "获取车辆轨迹")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "vin", value = "车架号", required = true, dataType = "String"),
			@ApiImplicitParam(name = "startTime", value = "开始时间 格式：2019-01-07 15:55:51", required = true, dataType = "String"),
			@ApiImplicitParam(name = "endTime", value = "结束时间 格式：2019-01-07 15:55:51", required = true, dataType = "String")
	})
	@GetMapping(value = "/trajectory/record")
	public ResponseResult<List<IovTrajectoryVo>> getTrajectory(@RequestParam String vin, @RequestParam String startTime, @RequestParam String endTime) {
		ResponseResult<List<IovTrajectoryVo>> result = new ResponseResult<>();
		try {
			if(StringUtils.isBlank(startTime) && StringUtils.isBlank(endTime)) {
				LocalDate date = LocalDate.now();
				LocalDateTime atStartOfDay = date.atStartOfDay();
				startTime = DateUtil.formatDate(atStartOfDay);
				endTime =  DateUtil.formatDate(DateUtil.getDayEnd(atStartOfDay));
			}
			return result.success(carBffService.getTrajectory(vin, startTime, endTime));
		} catch (Exception e) {
			logger.error("[getTrajectoryTime]获取车辆轨迹异常", e);
			result.error("获取车辆轨迹异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "根据ID修改车辆信息")
	@PostMapping(value = "/cars/modify")
	@OptionalLogConfig(methods="编辑车辆")
	public ResponseResult<Boolean> modifyCarDetail(@RequestBody CarDetailModifyVo modifyDto) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			return result.success(carBffService.modifyCarDetail(modifyDto));
		} catch (Exception e) {
			logger.error("[insurance/commercial/modify]根据ID修改车辆信息异常", e);
			result.error("根据ID修改车辆信息异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "获取车辆详细信息")
	@ApiImplicitParam(name = "carId", value = "车辆id", required = true, dataType = "Integer")
	@GetMapping(value = "/cars/detail")
	public ResponseResult<CarDetailVo> getCarDetail(@RequestParam Integer carId) {
		ResponseResult<CarDetailVo> result = new ResponseResult<>();
		try {
			return result.success(carBffService.getCarDetail(carId));
		} catch (Exception e) {
			logger.error("[cars/detail]获取车辆详细信息异常", e);
			result.error("获取车辆详细信息异常");
		}
		return result;
	}

    @Override
    @ApiOperation(value = "根据车辆id获取车辆详细信息（交强险，商业险）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "carId", value = "车辆id", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "type", value = "类型1：交强险，2：商业险", required = false, dataType = "Integer")
    })
    @GetMapping(value = "/cars/detail/insurance")
    public ResponseResult<List<CarInsuranceVo>> getInsuranceList(@RequestParam Integer carId, @RequestParam(name = "type", required = false) Integer type) {
        ResponseResult<List<CarInsuranceVo>> result = new ResponseResult<>();
        try {
            return result.success(insuranceBffService.getInsuranceList(carId, type));
        } catch (Exception e) {
            logger.error("[cars/detail]获取车辆详细信息异常", e);
            result.error("获取车辆详细信息异常");
        }
        return result;
    }

    @Override
    @ApiOperation(value = "根据车辆id获取车辆详细信息（事故）")
    @ApiImplicitParam(name = "carId", value = "车辆id", required = true, dataType = "Integer")
    @GetMapping(value = "/cars/detail/accident")
    public ResponseResult<List<AccidentBizVo>> getCarAccidentList(@RequestParam Integer carId) {
        ResponseResult<List<AccidentBizVo>> result = new ResponseResult<>();
        try {
            return result.success(accidentBffService.getCarAccidentList(carId));
        } catch (Exception e) {
            logger.error("[cars/detail]获取车辆详细信息异常", e);
            result.error("获取车辆详细信息异常");
        }
        return result;
    }

    @Override
    @ApiOperation(value = "根据车辆id获取车辆详细信息（检验）")
    @ApiImplicitParam(name = "carId", value = "车辆id", required = true, dataType = "Integer")
    @GetMapping(value = "/cars/detail/check")
    public ResponseResult<List<CarCheckVo>> getCarCheckListByCarId(Integer carId) {
        ResponseResult<List<CarCheckVo>> result = new ResponseResult<>();
        try {
            return result.success(carCheckBffService.getCarCheckListByCarId(carId));
        } catch (Exception e) {
            logger.error("[cars/detail]获取车辆详细信息异常", e);
            result.error("获取车辆详细信息异常");
        }
        return result;
    }

    @Override
    @ApiOperation(value = "根据车辆id获取车辆详细信息（违章）")
    @ApiImplicitParam(name = "carId", value = "车辆id", required = true, dataType = "Integer")
    @GetMapping(value = "/cars/detail/violation")
    public ResponseResult<List<CarsViolationVo>> getViolationListByCarId(Integer carId) {
        ResponseResult<List<CarsViolationVo>> result = new ResponseResult<>();
        try {
            return result.success(violationBffService.getCarsViolationByCarId(carId));
        } catch (Exception e) {
            logger.error("[cars/detail]获取车辆详细信息异常", e);
            result.error("获取车辆详细信息异常");
        }
        return result;
    }

	@Override
	@ApiOperation(value = "根据车辆id获取车辆详细信息（保养）")
	@ApiImplicitParam(name = "carId", value = "车辆id", required = true, dataType = "Integer")
	@GetMapping(value = "/cars/detail/maintenance")
	public ResponseResult<List<MaintenanceRecordVo>> getMaintenanceByCarId(Integer carId) {
		ResponseResult<List<MaintenanceRecordVo>> result = new ResponseResult<>();
		try {
			return result.success(maintenanceBffService.getMaintenanceByCarId(carId));
		} catch (Exception e) {
			logger.error("[cars/detail]根据车辆id获取车辆详细信息（保养）", e);
			result.error("根据车辆id获取车辆详细信息（保养）");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "导入车辆信息")
	@PostMapping(value = "/upload/vehicle/file")
	@OptionalLogConfig(methods="导入车辆")
	public ResponseResult<Boolean> uploadVehicleFile(MultipartFile file) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			if((null == file)||(file.getSize() == 0)) {
				result.error("文件为空");
				return result;
			}
			if((null == file)||(file.getSize() > 83886080)) {
				result.error("一次最多导入80M");
				return result;
			}
			if (!file.getOriginalFilename().matches("^.+\\.(?i)(xls)$") && !file.getOriginalFilename().matches("^.+\\.(?i)(xlsx)$")) {
				result.error("模板有误，请重新选择导入文件");
				return result;
			}
			//判断Excel文件的版本
			boolean isExcel2003=true;
			if (file.getOriginalFilename().matches("^.+\\.(?i)(xlsx)$")) {
				isExcel2003 = false;
			}
			InputStream is= file.getInputStream();
			Workbook wb=null;
			if (isExcel2003) {
				wb = new HSSFWorkbook(is);
			} else {
				wb = new XSSFWorkbook(is);
			}
			//获取Excel文件的第一页sheet，判断是否有信息
			Sheet sheet=wb.getSheetAt(0);
			Row row=sheet.getRow(0);
			if(row.getPhysicalNumberOfCells() != 8) {
				result.error("模板有误，请重新选择导入文件");
				return result;
			}
			final UserEntity currentLoginUser = tokenUtil.getUser();
			taskExecutor.execute(new Runnable() {
				@Override
				public void run() {
					try {
						carBffService.uploadVehicleFile(sheet, currentLoginUser);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			});
		} catch (Exception e) {
			logger.error("[uploadVehicleFile]导入车辆信息异常", e);
			result.error("导入车辆信息异常");
			return result;
		}
		return result.success("导入结果已发至您邮箱，请登录邮箱查看导入结果！", null);
	}


	@Override
	@ApiOperation(value = "上传车辆的图片zip包")
	@PostMapping(value = "/upload/vehicle/pdf")
	@OptionalLogConfig(methods="上传车辆的图片")
	public ResponseResult<Boolean> uploadVehicleImgZip(MultipartFile purchaseInvoiceFile,  MultipartFile factoryCertificateFile,MultipartFile conformityCertificateFile) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			//判断后缀格式
			if(((null == purchaseInvoiceFile)||(purchaseInvoiceFile.getSize() == 0))&&((null == factoryCertificateFile)||(factoryCertificateFile.getSize() == 0))
					&&((null == conformityCertificateFile)||(conformityCertificateFile.getSize() == 0))) {
				result.error("文件为空");
				return result;
			}
			if((null != purchaseInvoiceFile)&&!purchaseInvoiceFile.getOriginalFilename().endsWith(".zip")) {
				result.error("购车发票文件类型错误");
				return result;
			}
			if((null != factoryCertificateFile)&&!factoryCertificateFile.getOriginalFilename().endsWith(".zip")) {
				result.error("出厂合格证文件类型错误");
				return result;
			}
			if((null != conformityCertificateFile)&&!conformityCertificateFile.getOriginalFilename().endsWith(".zip")) {
				result.error("一致性合格证文件类型错误");
				return result;
			}
			if((null != purchaseInvoiceFile)&&(purchaseInvoiceFile.getSize() > 83886080)) {
				result.error("购车发票一次最多导入80M");
				return result;
			}
			if((null != factoryCertificateFile)&&(factoryCertificateFile.getSize() > 83886080)) {
				result.error("出场合格证一次最多导入80M");
				return result;
			}
			if((null != conformityCertificateFile)&&(conformityCertificateFile.getSize() > 83886080)) {
				result.error("一致性合格证一次最多导入80M");
				return result;
			}
			//上传oss
			//修改数据库
			final UserEntity currentLoginUser = tokenUtil.getUser();
			taskExecutor.execute(new Runnable() {
				@Override
				public void run() {
					try {
						carBffService.uploadVehiclePdfFile(purchaseInvoiceFile, factoryCertificateFile, conformityCertificateFile, currentLoginUser, zipFilePath);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			});
		} catch (Exception e) {
			logger.error("[uploadVehicleFile]导入车辆信息异常", e);
			result.error("导入车辆信息异常");
			return result;
		}
		return result.success();
	}

	@Override
	@ApiOperation(value = "获取事故列表信息")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "licencePlate", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "userName", value = "用户", required = false, dataType = "String"),
			@ApiImplicitParam(name = "liabilityType", value = "责任类型（0：无责，1：全责，2：主责，3：同责，4：次责）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "isCasualty", value = "是否有人伤（0：无人伤，1：有人伤）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "accidentType", value = "事故类型（1:单方事故，2：双方事故，3：多方事故，4：停放受损，5：车辆盗抢，6：车辆自燃，7：车辆涉水，8：重大自然灾害）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "accidentStartTime", value = "出险开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "accidentEndTime", value = "出险结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "status", value = "事故状态（0：全部，1：事故未确认，2：事故已确认，3：结案未确认，4：已结案，5：无效报备）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "sortName", value = "排序字段", required = false, dataType = "String"),
			@ApiImplicitParam(name = "sortWay", value = "排序方式 asc:正序，desc:倒叙", required = false, dataType = "String"),
			@ApiImplicitParam(name = "pageNum", value = "页码", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "Integer")

	})
	@GetMapping(value = "/accident/list")
	public ResponseResult<Paged<AccidentBizVo>> getCarAccidentPage(@RequestParam Map<String, Object> map, @RequestParam Integer pageNum, @RequestParam Integer pageSize) {
		ResponseResult<Paged<AccidentBizVo>> result = new ResponseResult<>();
		try {
			return result.success(accidentBffService.getCarAccidentPage(map, pageNum, pageSize));
		} catch (Exception e) {
			logger.error("[accident/list]获取事故列表信息异常", e);
			result.error("获取事故列表信息异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "获取事故详细信息")
	@ApiImplicitParam(name = "accidentId", value = "事故id", required = true, dataType = "Integer")
	@GetMapping(value = "/accident/detail")
	public ResponseResult<AccidentDetailVo> getAccident(@RequestParam Integer accidentId) throws Exception {
		ResponseResult<AccidentDetailVo> result = new ResponseResult<>();
		try {
			return result.success(accidentBffService.getAccident(accidentId));
		} catch (Exception e) {
			logger.error("[accident/detail]获取事故详细信息异常", e);
			result.error("获取事故详细信息异常");
		}
		return result;
	}


    @Override
    @ApiOperation(value = "验证事故、结案是否重复提交")
    @ApiImplicitParam(name = "accidentId", value = "事故id", required = true, dataType = "Integer")
    @GetMapping(value = "/accident/verify/repeat")
    public ResponseResult<AccidentVerifyBizVo> verifyRepeat(@RequestParam Integer accidentId, @RequestParam Integer version) throws Exception {
        ResponseResult<AccidentVerifyBizVo> result = new ResponseResult<>();
        try {
            return result.success(accidentBffService.verifyRepeat(accidentId, version));
        } catch (Exception e) {
            logger.error("[verifyRepeat]验证事故、结案是否重复提交异常", e);
            result.error("验证事故、结案是否重复提交异常");
        }
        return result;
    }

	@Override
	@ApiOperation(value = "根据ID审核事故信息")
	@PostMapping(value = "/accident/modify")
	@OptionalLogConfig(methods="审核事故")
	public ResponseResult<Boolean> modifyExamineAccident(@RequestBody  AccidentExamineCreateVo createDto) throws Exception {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			return result.success(accidentBffService.modifyExamineAccident(createDto));
		} catch (Exception e) {
			logger.error("[accident/modify]根据ID审核事故信息异常", e);
			result.error("根据ID审核事故信息异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "获取保养列表信息")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "licencePlate", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "type", value = "1-待保养，0-待审核，8-审核记录", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "totalStartMileage", value = "已行驶开始里程", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "totalEndMileage", value = "已行驶结束里程", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "maintainableStartDate", value = "开始保养时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "maintainableEndDate", value = "结束保养时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "purchaseStartDate", value = "采购开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "purchaseEndDate", value = "采购结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "checkStartDate", value = "审核开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "checkEndDate", value = "审核结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "examineStatus", value = "审核状态 3-审核通过，4-审核驳回", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "sortName", value = "排序字段", required = false, dataType = "String"),
			@ApiImplicitParam(name = "sortWay", value = "排序方式 asc:正序，desc:倒叙", required = false, dataType = "String"),
			@ApiImplicitParam(name = "pageNum", value = "页码", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "Integer")

	})
	@GetMapping(value = "/maintenance/list")
	public ResponseResult<Paged<MaintenanceBizVo>> getMaintenancePage(@RequestParam Map<String, Object> mapParam, @RequestParam Integer pageNum, @RequestParam Integer pageSize) {
		ResponseResult<Paged<MaintenanceBizVo>> result = new ResponseResult<>();
		try {
			String totalStartMileage = ObjectCastUtil.castString(mapParam.get("totalStartMileage"));
			String totalEndMileage = ObjectCastUtil.castString(mapParam.get("totalEndMileage"));
			if(StringUtils.isNoneBlank(totalStartMileage) && !ValidateUtil.isPositiveInteger(totalStartMileage)){
				return result.error("已行驶里程,请输入大于等于0的整数");
			}
			if(StringUtils.isNoneBlank(totalEndMileage) && !ValidateUtil.isPositiveInteger(totalEndMileage)){
				return result.error("已行驶里程,请输入大于等于0的整数");
			}

			return result.success(maintenanceBffService.getMaintenancePage(mapParam, pageNum, pageSize));
		} catch (Exception e) {
			logger.error("[maintenance/list]查询保养信息异常", e);
			result.error("查询保养信息异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "根据保养ID获取保养信息")
	@ApiImplicitParam(name = "maintenanceId", value = "保养id", required = true, dataType = "Integer")
	@GetMapping(value = "/maintenance/detail")
	public ResponseResult<MaintenanceDetailVo> getMaintenanceById(@RequestParam Integer maintenanceId) {
		ResponseResult<MaintenanceDetailVo> result = new ResponseResult<>();
		try {
			return result.success(maintenanceBffService.getMaintenanceById(maintenanceId));
		} catch (Exception e) {
			logger.error("[getMaintenanceById]根据保养ID获取保养信息", e);
			result.error("根据保养ID获取保养信息");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "根据保养记录ID获取保养记录信息")
	@ApiImplicitParam(name = "maintenanceId", value = "保养记录id", required = true, dataType = "Integer")
	@GetMapping(value = "/maintenance/record/detail")
	public ResponseResult<MaintenanceRecordVo> getMaintenanceRecordById(Integer maintenanceId) {
		ResponseResult<MaintenanceRecordVo> result = new ResponseResult<>();
		try {
			return result.success(maintenanceBffService.getMaintenanceRecordById(maintenanceId));
		} catch (Exception e) {
			logger.error("[getMaintenanceById]根据保养ID获取保养信息", e);
			result.error("根据保养ID获取保养信息");
		}
		return result;
	}


	@Override
	@ApiOperation(value = "创建保养历史信息")
	@PostMapping(value = "/maintenance/log/create")
	@OptionalLogConfig(methods="新增保养")
	public ResponseResult<Boolean> createMaintenanceLog(@RequestBody MaintenanceLogCreateVo maintenanceLogCreateVo) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			return result.success(maintenanceBffService.createMaintenanceLog(maintenanceLogCreateVo));
		} catch (Exception e) {
			logger.error("创建保养历史异常", e);
			result.error("创建保养历史异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "审核保养历史信息")
	@PostMapping(value = "/maintenance/log/examine")
	@OptionalLogConfig(methods="审核保养")
	public ResponseResult<Integer> modifyMaintenanceCheck(@RequestBody MaintenanceLogModifyVo modifyVo) {
		ResponseResult<Integer> result = new ResponseResult<>();
		try {
			return result.success(maintenanceBffService.modifyMaintenanceCheck(modifyVo));
		} catch (Exception e) {
			logger.error("审核保养历史信息异常", e);
			result.error("审核保养历史信息异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "获取车辆违章列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "licencePlate", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "status", value = "违章处理状态(0:全部，1:未处理未交费, 2:已处理未交费, 3:已处理已交费)", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "startTime", value = "开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endTime", value = "结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "pageNum", value = "页码", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "Integer")

	})
	@GetMapping(value = "/violation/list")
	public ResponseResult<Paged<CarsViolationVo>> getCarsViolationPaged(@RequestParam Map<String, Object> params, @RequestParam Integer pageNum, @RequestParam Integer pageSize) {
		ResponseResult<Paged<CarsViolationVo>> result = new ResponseResult<>();
		try {
			result.success(violationBffService.getCarsViolationPaged(params, pageNum, pageSize));
		} catch (Exception e) {
			// 记录异常，返回异常信息
			logger.error("[getCarsViolationPaged]获取车辆违章列表异常", e);
			result.error("获取车辆违章列表异常:" + e.getMessage());
		}
		return result;
	}

	@Override
	@ApiOperation(value = "导入交强险信息（excel）")
	@PostMapping(value = "/upload/insurance/excelFile")
	@OptionalLogConfig(methods="导入交强险")
	public ResponseResult<Boolean> uploadInsuranceExcelFile(MultipartFile excelFile) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		if((null == excelFile)||(excelFile.getSize() == 0)) {
			return result.error("文件为空");
		}
		if((null == excelFile)||(excelFile.getSize() > 83886080)) {
			return result.error("一次最多导入80M");
		}
		if (!excelFile.getOriginalFilename().matches("^.+\\.(?i)(xls)$") && !excelFile.getOriginalFilename().matches("^.+\\.(?i)(xlsx)$")) {
			return result.error(ResponseCodeEnum.UNKNOWN_ERROR.getCode(), "上传文件格式不正确");
		}

		try {
			final UserEntity currentLoginUser = tokenUtil.getUser();
			taskExecutor.execute(new Runnable() {
				@Override
				public void run() {
					try {
						insuranceBffService.uploadInsuranceExcelFile(excelFile, currentLoginUser);
					} catch (Exception e) {
						logger.error("【导入交强险信息】失败", e);
					}
				}
			});
			return  result.success("导入结果已发至您邮箱，请登录邮箱查看导入结果！", true);
		} catch (BizException e) {
			logger.error("[uploadInsuranceFile]导入交强险异常:", e);
			result.error(e.getExceptionCode(), e.getMessage());
		} catch (Exception e) {
			logger.error("[uploadInsuranceFile]导入交强险信息异常", e);
			result.error("导入交强险信息异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "导入交强险保单pdf（pdf）")
	@PostMapping(value = "/upload/insurance/pdfFile")
	@OptionalLogConfig(methods="导入交强险保单")
	public ResponseResult<Boolean> uploadInsurancePdfFile(MultipartFile pdfFile) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			if(pdfFile == null || pdfFile.getSize() <= 0) {
				return result.error("文件为空");
			}
			if (pdfFile.getSize() > 83886080) {
				return result.error("一次最多导入80M");
			}


			final UserEntity currentLoginUser = tokenUtil.getUser();
			taskExecutor.execute(new Runnable() {
				@Override
				public void run() {
					try {
						insuranceBffService.uploadInsurancePdfFile(pdfFile, currentLoginUser, OSSFileFolderEnum.INSURANCE);
					} catch (Exception e) {
						logger.error("【导入交强险保单pdf】失败", e);
					}
				}
			});
			return result.success("导入结果已发至您邮箱，请登录邮箱查看导入结果！", true);
		} catch (Exception e) {
			logger.error("[uploadInsurancePdfFile]导入交强险保单图片异常", e);
			result.error("导入异常");
		}
		return  result;
	}

	@Override
	@ApiOperation(value = "导入商业险信息（excel）")
	@PostMapping(value = "/upload/commercial/excelFile")
	@OptionalLogConfig(methods="导入商业险")
	public ResponseResult<Boolean> uploadCommercialExcelFile(MultipartFile excelFile) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		if((null == excelFile)||(excelFile.getSize() == 0)) {
			return result.error("文件为空");
		}
		if((null == excelFile)||(excelFile.getSize() > 83886080)) {
			return result.error("一次最多导入80M");
		}
		if (!excelFile.getOriginalFilename().matches("^.+\\.(?i)(xls)$") && !excelFile.getOriginalFilename().matches("^.+\\.(?i)(xlsx)$")) {
			return result.error(ResponseCodeEnum.UNKNOWN_ERROR.getCode(), "上传文件格式不正确");
		}

		try {
			final UserEntity currentLoginUser = tokenUtil.getUser();
			taskExecutor.execute(new Runnable() {
				@Override
				public void run() {
					try {
						insuranceBffService.uploadInsuranceCommercialExcelFile(excelFile, currentLoginUser);
					} catch (Exception e) {
						logger.error("【导入商业险信息】失败", e);
					}
				}
			});
			return  result.success("导入结果已发至您邮箱，请登录邮箱查看导入结果！", true);
		} catch (BizException e) {
			logger.error("[uploadCommercialFile]导入商业险异常:", e);
			result.error(e.getExceptionCode(), e.getMessage());
		} catch (Exception e) {
			logger.error("[uploadCommercialFile]导入商业险信息异常", e);
			result.error("导入商业险信息异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "导入商业险保单pdf（pdf）")
	@PostMapping(value = "/upload/commercial/pdfFile")
	@OptionalLogConfig(methods="导入商业险保单")
	public ResponseResult<Boolean> uploadCommercialPdfFile(MultipartFile pdfFile) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			if(pdfFile == null || pdfFile.getSize() <= 0) {
				return result.error("文件为空");
			}
			if (pdfFile.getSize() > 83886080) {
				return result.error("一次最多导入80M");
			}


			final UserEntity currentLoginUser = tokenUtil.getUser();
			taskExecutor.execute(new Runnable() {
				@Override
				public void run() {
					try {
						insuranceBffService.uploadInsurancePdfFile(pdfFile, currentLoginUser, OSSFileFolderEnum.COMMERCIAL);
					} catch (Exception e) {
						logger.error("【导入商业险保单pdf】失败", e);
					}
				}
			});
			return  result.success("导入结果已发至您邮箱，请登录邮箱查看导入结果！", true);
		} catch (Exception e) {
			logger.error("[uploadCommercialPdfFile]导入交强险保单图片异常", e);
			result.error("导入异常");
		}
		return result;
	}
	@Override
	@ApiOperation(value = "车辆列表导出")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "carIdList", value = "车辆id(选择导出使用)", required = false, dataType = "String"),
			@ApiImplicitParam(name = "licencePlate", value = "车牌", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vehicleId", value = "车型Id", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "purchaseStartDate", value = "采购开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "purchaseEndDate", value = "采购结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "stockId", value = "仓库id", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "stockType", value = "仓库类型(1:中转库，2：门店)", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "vehicleType", value = "车辆类型（0：新车，1：二手车）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "plateStatus", value = "上牌状态：0：全部，1：未上牌，2：已上牌", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "status", value = "空：全部， 1：未入网，2：已入网，3：在库车辆，4：在店车辆，5：业务中，6：非业务", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "vehicleStatus", value = "空：全部， 0：待出租，1：已出租，2：不可租", required = false, dataType = "Integer")
			 })
	@GetMapping(value = "/download/car/list")
	@OptionalLogConfig(methods="车辆导出")
	public void getCarListDownload(HttpServletRequest request, HttpServletResponse response,
											   @RequestParam Map<String, Object> selectParams) {
		try {
			if (selectParams == null) {
				selectParams = new HashMap<>();
			}

			List<CarVo> carList = carBffService.getCarListDownload(selectParams);
			String fileName = "车辆列表(" + DateUtil.formatDate(LocalDate.now()) + ").xlsx";
			// 生成excel
			SXSSFWorkbook xssBook = PoiExcelUtil.getCarListDownload(carList);
			// 下载
			DownloadFileUtil.downloadExcel(request, response, fileName, xssBook);
		} catch (BizException e) {
			logger.error("[getCarListDownload]车辆列表导出异常:", e);
		} catch (Exception e) {
			logger.error("[getCarListDownload]车辆列表导出异常:", e);
		}
	}

	@Override
	@ApiOperation(value = "车辆列表导出查询")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "carIdList", value = "车辆id(选择导出使用)", required = false, dataType = "String"),
			@ApiImplicitParam(name = "licencePlate", value = "车牌", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vehicleId", value = "车型Id", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "purchaseStartDate", value = "采购开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "purchaseEndDate", value = "采购结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "stockId", value = "仓库id", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "stockType", value = "仓库类型(1:中转库，2：门店)", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "vehicleType", value = "车辆类型（0：新车，1：二手车）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "plateStatus", value = "上牌状态：0：全部，1：未上牌，2：已上牌", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "status", value = "空：全部， 1：未入网，2：已入网，3：在库车辆，4：在店车辆，5：业务中，6：非业务", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "vehicleStatus", value = "空：全部， 0：待出租，1：已出租，2：不可租", required = false, dataType = "Integer") })
	@GetMapping(value = "/download/car/list/query")
	public ResponseResult<Boolean> getCarListDownloadQuery(HttpServletRequest request, HttpServletResponse response,
			@RequestParam Map<String, Object> selectParams) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			if (selectParams == null) {
				selectParams = new HashMap<>();
			}

			// 查询导出条数
			Long total = carBffService.getCarListDownloadCount(selectParams);
			if (total != null && total > ContantsUtil.DOWNLOAD_EXCEL_MAX_NUM) {
				// 大于最大导出条数，异步发邮件
				carBffService.getCarListDownloadEmail(selectParams, tokenUtil.getUser());
				// 返回提示
				result.success("已将导出数据发送至您的邮箱", true);
			} else {
				// 小于最大导出条数，提示前端调用直接导出接口
				result.success(false);
			}
		} catch (BizException e) {
            logger.error("[getCarListDownload]车辆列表导出异常:", e);
			result.error("车辆列表导出异常");
        } catch (Exception e) {
            logger.error("[getCarListDownload]车辆列表导出异常:", e);
			result.error("车辆列表导出异常");
        }

		return result;
	}

	@Override
	@ApiOperation(value = "年检列表导出")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "inspectionIdList", value = "年检id(选择导出使用)", required = false, dataType = "String"),
			@ApiImplicitParam(name = "yearlyInspectStatus", value = "年检状态NORMAL(0, 即将过期,1, 过期);", required = true, dataType = "String"),
			@ApiImplicitParam(name = "licencePlate", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "addressType", value = "车辆位置类型（1：中转库，2：门店）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "addressId", value = "车辆位置Id", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "inspectStartDate", value = "年检开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "inspectEndDate", value = "年检结束时间", required = false, dataType = "String")
	})
	@GetMapping(value = "/download/yearly/list")
	@OptionalLogConfig(methods="年检导出")
	public void getYearlyInspectDownload(HttpServletRequest request, HttpServletResponse response,
										 @RequestParam(name = "inspectionIdList", required = false) String inspectionIdList,
										 @RequestParam int yearlyInspectStatus,
										 @RequestParam(name = "licencePlate", required = false)String licencePlate,
										 @RequestParam(name = "vin", required = false) String vin,
										 @RequestParam(name = "addressType", required = false) Integer addressType,
										 @RequestParam(name = "addressId", required = false) Integer addressId,
										 @RequestParam(name = "inspectStartDate", required = false) String inspectStartDate,
										 @RequestParam(name = "inspectEndDate", required = false) String inspectEndDate) {
		try {
			List<CarYearlyInspectVo> yearlyInspectDownload = yearlyInspectBffService.getYearlyInspectDownload(inspectionIdList,yearlyInspectStatus, licencePlate, vin, addressType, addressId, inspectStartDate, inspectEndDate);

			String fileName = "年检列表(" + DateUtil.formatDate(LocalDate.now()) + ").xlsx";
			// 生成excel
			SXSSFWorkbook xssBook = PoiExcelUtil.getYearlyInspectDownload(yearlyInspectDownload);
			// 下载
			DownloadFileUtil.downloadExcel(request, response, fileName, xssBook);
		} catch (BizException e) {
			logger.error("[getYearlyInspectDownload]年检列表导出异常:", e);
		} catch (Exception e) {
			logger.error("[getYearlyInspectDownload]年检列表导出异常:", e);
		}
	}

	@Override
	@ApiOperation(value = "年检列表导出")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "inspectionIdList", value = "年检id(选择导出使用)", required = false, dataType = "String"),
			@ApiImplicitParam(name = "yearlyInspectStatus", value = "年检状态NORMAL(0, 即将过期,1, 过期);", required = true, dataType = "String"),
			@ApiImplicitParam(name = "licencePlate", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "addressType", value = "车辆位置类型（1：中转库，2：门店）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "addressId", value = "车辆位置Id", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "inspectStartDate", value = "年检开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "inspectEndDate", value = "年检结束时间", required = false, dataType = "String") })
	@GetMapping(value = "/download/yearly/list/query")
	public ResponseResult<Boolean> getYearlyInspectDownloadQuery(HttpServletRequest request,
			HttpServletResponse response,
			@RequestParam(name = "inspectionIdList", required = false) String inspectionIdList,
			@RequestParam int yearlyInspectStatus,
			@RequestParam(name = "licencePlate", required = false) String licencePlate,
			@RequestParam(name = "vin", required = false) String vin,
			@RequestParam(name = "addressType", required = false) Integer addressType,
			@RequestParam(name = "addressId", required = false) Integer addressId,
			@RequestParam(name = "inspectStartDate", required = false) String inspectStartDate,
			@RequestParam(name = "inspectEndDate", required = false) String inspectEndDate) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			// 查询导出条数
			Long total = yearlyInspectBffService.getYearlyInspectDownloadCount(inspectionIdList, yearlyInspectStatus,
					licencePlate, vin, addressType, addressId, inspectStartDate, inspectEndDate);

			if (total != null && total > ContantsUtil.DOWNLOAD_EXCEL_MAX_NUM) {
				// 大于最大导出条数，异步发邮件
				yearlyInspectBffService.getYearlyInspectDownloadEmail(inspectionIdList, yearlyInspectStatus,
						licencePlate, vin, addressType, addressId, inspectStartDate, inspectEndDate,
						tokenUtil.getUser());
				// 返回提示
				result.success("已将导出数据发送至您的邮箱", true);
			} else {
				// 小于最大导出条数，提示前端调用直接导出接口
				result.success(false);
			}
		} catch (BizException e) {
			logger.error("[getYearlyInspectDownload]年检列表导出异常:", e);
			result.error("年检列表导出异常");
		} catch (Exception e) {
			logger.error("[getYearlyInspectDownload]年检列表导出异常:", e);
			result.error("年检列表导出异常");
		}

		return result;
	}

	@ApiOperation(value = "车辆违章列表导出")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "ids", value = "违章id集合(选择导出使用)", required = false, dataType = "String"),
			@ApiImplicitParam(name = "licencePlate", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "status", value = "违章处理状态(0:全部，1:未处理未交费, 2:已处理未交费, 3:已处理已交费)", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "startTime", value = "开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endTime", value = "结束时间", required = false, dataType = "String")
	})
	@GetMapping(value = "/download/violation/list")
	@Override
	public void getCarsViolationDownload(HttpServletRequest request, HttpServletResponse response,
			 @RequestParam Map<String, Object> map) {
		try {
			List<CarsViolationVo> list = carDownloadBffService.getCarsViolationDownload(map);
			String fileName = "车辆违章列表(" + DateUtil.formatDate(LocalDate.now()) + ").xlsx";
			// 生成excel
			XSSFWorkbook xssBook = PoiExcelUtil.getCarsViolationDownload(list);
			// 下载
			DownloadFileUtil.downloadExcel(request, response, fileName, xssBook);
		} catch (BizException e) {
			logger.error("[getCarsViolationDownload]车辆违章列表导出异常:", e);
		} catch (Exception e) {
			logger.error("[getCarsViolationDownload]车辆违章列表导出异常:", e);
		}
	}
	
	@ApiOperation(value = "车辆违章列表导出")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "ids", value = "违章id集合(选择导出使用)", required = false, dataType = "String"),
			@ApiImplicitParam(name = "licencePlate", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "status", value = "违章处理状态(0:全部，1:未处理未交费, 2:已处理未交费, 3:已处理已交费)", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "startTime", value = "开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endTime", value = "结束时间", required = false, dataType = "String") })
	@GetMapping(value = "/download/violation/list/query")
	@Override
	public ResponseResult<Boolean> getCarsViolationDownloadQuery(HttpServletRequest request,
			HttpServletResponse response, @RequestParam Map<String, Object> selectParams) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			if (selectParams == null) {
				selectParams = new HashMap<>();
			}

			// 查询导出条数
			Long total = carDownloadBffService.getCarsViolationDownloadCount(selectParams);
			if (total != null && total > ContantsUtil.DOWNLOAD_EXCEL_MAX_NUM) {
				// 大于最大导出条数，异步发邮件
				carDownloadBffService.getCarsViolationDownloadEmail(selectParams, tokenUtil.getUser());
				// 返回提示
				result.success("已将导出数据发送至您的邮箱", true);
			} else {
				// 小于最大导出条数，提示前端调用直接导出接口
				result.success(false);
			}
		} catch (BizException e) {
			logger.error("[getCarListDownload]车辆违章导出异常:", e);
			result.error("车辆违章导出异常");
		} catch (Exception e) {
			logger.error("[getCarListDownload]车辆违章导出异常:", e);
			result.error("车辆违章导出异常");
		}

		return result;
	}

	@Override
	@ApiOperation(value = "事故列表导出")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "ids", value = "事故id集合(选择导出使用)", required = false, dataType = "String"),
			@ApiImplicitParam(name = "licencePlate", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "userName", value = "用户", required = false, dataType = "String"),
			@ApiImplicitParam(name = "liabilityType", value = "责任类型（0：无责，1：全责，2：主责，3：同责，4：次责）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "isCasualty", value = "是否有人伤（0：无人伤，1：有人伤）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "accidentType", value = "事故类型（1:单方事故，2：双方事故，3：多方事故，4：停放受损，5：车辆盗抢，6：车辆自燃，7：车辆涉水，8：重大自然灾害）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "accidentStartTime", value = "出险开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "accidentEndTime", value = "出险结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "status", value = "事故状态（0：全部，1：事故未确认，2：事故已确认，3：结案未确认，4：已结案，5：无效报备）", required = true, dataType = "Integer")
	})
	@GetMapping(value = "/download/accident/list")
	@OptionalLogConfig(methods="事故列表导出")
	public void getAccidentDownload(HttpServletRequest request, HttpServletResponse response,
			 @RequestParam Map<String, Object> map) {
		try {
			List<AccidentDownloadVo> list = carDownloadBffService.getAccidentDownload(map);
			String fileName = "事故管理列表(" + DateUtil.formatDate(LocalDate.now()) + ").xlsx";
			// 生成excel
			XSSFWorkbook xssBook = PoiExcelUtil.getAccidentDownload(list);
			// 下载
			DownloadFileUtil.downloadExcel(request, response, fileName, xssBook);
		} catch (BizException e) {
			logger.error("[getAccidentDownload]车辆事故管理列表导出异常:", e);
		} catch (Exception e) {
			logger.error("[getAccidentDownload]车辆事故管理列表导出异常:", e);
		}
		
	}

	@Override
	@ApiOperation(value = "事故列表导出查询")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "ids", value = "事故id集合(选择导出使用)", required = false, dataType = "String"),
			@ApiImplicitParam(name = "licencePlate", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "userName", value = "用户", required = false, dataType = "String"),
			@ApiImplicitParam(name = "liabilityType", value = "责任类型（0：无责，1：全责，2：主责，3：同责，4：次责）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "isCasualty", value = "是否有人伤（0：无人伤，1：有人伤）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "accidentType", value = "事故类型（1:单方事故，2：双方事故，3：多方事故，4：停放受损，5：车辆盗抢，6：车辆自燃，7：车辆涉水，8：重大自然灾害）", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "accidentStartTime", value = "出险开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "accidentEndTime", value = "出险结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "status", value = "事故状态（0：全部，1：事故未确认，2：事故已确认，3：结案未确认，4：已结案，5：无效报备）", required = true, dataType = "Integer") })
	@GetMapping(value = "/download/accident/list/query")
	public ResponseResult<Boolean> getAccidentDownloadQuery(HttpServletRequest request, HttpServletResponse response,
			Map<String, Object> selectParams) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			if (selectParams == null) {
				selectParams = new HashMap<>();
			}

			// 查询导出条数
			Long total = carDownloadBffService.getAccidentDownloadCount(selectParams);
			if (total != null && total > ContantsUtil.DOWNLOAD_EXCEL_MAX_NUM) {
				// 大于最大导出条数，异步发邮件
				carDownloadBffService.getAccidentDownloadEmail(selectParams, tokenUtil.getUser());
				// 返回提示
				result.success("已将导出数据发送至您的邮箱", true);
			} else {
				// 小于最大导出条数，提示前端调用直接导出接口
				result.success(false);
			}
		} catch (BizException e) {
			logger.error("[getCarListDownload]车辆事故导出异常:", e);
			result.error("车辆事故导出异常");
		} catch (Exception e) {
			logger.error("[getCarListDownload]车辆事故导出异常:", e);
			result.error("车辆事故导出异常");
		}

		return result;
	}


	@Override
	@ApiOperation(value = "保险信息导出")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "type", value = "保险类别：1-交强险，2-商业险", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "ids", value = "保单ids(选择导出使用)", required = false, dataType = "String"),
			@ApiImplicitParam(name = "licencePlate", value = "车牌", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "code", value = "保单号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "status", value = "1:在保，2：过保保单,3:未生效保单 ", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "insuranceCompanyId", value = "保险公司ID", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "insureStartTime", value = "投保开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "insureEndTime", value = "投保结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "beginStartTime", value = "起保开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "beginEndTime", value = "起保结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endStartTime", value = "终保开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endEndTime", value = "终保结束时间", required = false, dataType = "String")
	})
	@GetMapping(value = "/download/insurance/list")
	@OptionalLogConfig(methods="保险导出")
	public void getInsuranceListDownload(HttpServletRequest request, HttpServletResponse response,
			@RequestParam Map<String, Object> selectParams) {
		// ResponseResult<String> result = new ResponseResult<>();
		try {
			String fileName = null;
			SXSSFWorkbook sxssBook = null;

			int carInsuranceType = ObjectCastUtil.castInt(selectParams.get("type"));
			if (carInsuranceType == 0) {
				logger.error("[getInsuranceListDownload]车辆保险信息导出异常，保险类别(" + selectParams.get("type") + ")错误");
			} else if (carInsuranceType == CarInsuranceTypeEnum.COMPULSORY_INSURANCE.getValue()) {
				// 交强险
				List<CarInsuranceVo> insuranceList = carDownloadBffService.getInsuranceListDownload(selectParams);
				// 文件名
				fileName = "交强险列表(" + DateUtil.formatDate(LocalDate.now()) + ").xlsx";
				// 生成excel
				sxssBook = PoiExcelUtil.getInsuranceListDownload(insuranceList);
			} else if (carInsuranceType == CarInsuranceTypeEnum.COMMERCIAL_INSURANCE.getValue()) {
				// 商业险
				List<CarInsuranceVo> insuranceList = carDownloadBffService.getInsuranceListDownload(selectParams);
				// 文件名
				fileName = "商业险列表(" + DateUtil.formatDate(LocalDate.now()) + ").xlsx";
				// 生成excel
				sxssBook = PoiExcelUtil.getCommercialInsuranceListDownload(insuranceList);
			} else {
				logger.error("[getInsuranceListDownload]车辆保险信息导出异常，保险类别(" + selectParams.get("type") + ")错误");
			}
			// 下载
			DownloadFileUtil.downloadExcel(request, response, fileName, sxssBook);
		} catch (BizException e) {
			logger.error("[getInsuranceListDownload]车辆保养列表导出异常:", e);
		} catch (Exception e) {
			logger.error("[getInsuranceListDownload]车辆保养列表导出异常:", e);
		}
	}

	@Override
	@ApiOperation(value = "保险信息导出查询")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "type", value = "保险类别：1-交强险，2-商业险", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "ids", value = "保单ids(选择导出使用)", required = false, dataType = "String"),
			@ApiImplicitParam(name = "licencePlate", value = "车牌", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "code", value = "保单号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "status", value = "1:在保，2：过保保单,3:未生效保单 ", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "insuranceCompanyId", value = "保险公司ID", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "insureStartTime", value = "投保开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "insureEndTime", value = "投保结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "beginStartTime", value = "起保开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "beginEndTime", value = "起保结束时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endStartTime", value = "终保开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endEndTime", value = "终保结束时间", required = false, dataType = "String") })
	@GetMapping(value = "/download/insurance/list/query")
	public ResponseResult<Boolean> getInsuranceListDownloadQuery(HttpServletRequest request,
			HttpServletResponse response, @RequestParam Map<String, Object> selectParams) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			if (selectParams == null) {
				selectParams = new HashMap<>();
			}

			int carInsuranceType = ObjectCastUtil.castInt(selectParams.get("type"));

			// 查询导出条数
			Long total = carDownloadBffService.getInsuranceListDownloadCount(selectParams);
			if (total != null && total > ContantsUtil.DOWNLOAD_EXCEL_MAX_NUM) {
				// 大于最大导出条数，异步发邮件
				carDownloadBffService.getInsuranceListDownloadEmail(selectParams, carInsuranceType,
						tokenUtil.getUser());
				// 返回提示
				result.success("已将导出数据发送至您的邮箱", true);
			} else {
				// 小于最大导出条数，提示前端调用直接导出接口
				result.success(false);
			}
		} catch (BizException e) {
			logger.error("[getInsuranceListDownload]车辆保养列表导出异常:", e);
			result.error("车辆保险信息导出异常");
		} catch (Exception e) {
			logger.error("[getInsuranceListDownload]车辆保养列表导出异常:", e);
			result.error("车辆保险信息导出异常");
		}

		return result;
	}

	@Override
	@ApiOperation(value = "获取围栏异常的列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "licencePlate", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "fenceName", value = "围栏名称", required = false, dataType = "String"),
			@ApiImplicitParam(name = "stockId", value = "仓库id   同车辆列表的传值方式一样", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "stockType", value = "仓库类型(1:中转库，2：门店)", required = false, dataType = "Integer"),
	})
	@GetMapping(value = "/fence/exception/list")
	public ResponseResult<Paged<CarsFenceExceptionVo>> getCarsFenceExceptionPaged(@RequestParam Map<String, Object> params, Integer pageNum, Integer pageSize) {
		ResponseResult<Paged<CarsFenceExceptionVo>> result = new ResponseResult<>();
		try {
			return result.success(carFenceExceptionBffService.getCarsFenceExceptionPaged(params, pageNum, pageSize));
		} catch (Exception e) {
			logger.error("[getCarsFenceExceptionDetail]获取围栏异常的列表", e);
			result.error("获取围栏异常的列表异常"+e);
		}
		return result;
	}

	@Override
	@ApiOperation(value = "获取围栏异常的详细信息")
	@ApiImplicitParam(name = "fenceExceptionId", value = "围栏异常id", required = true, dataType = "Integer")
	@GetMapping(value = "/fence/exception/detail")
	public ResponseResult<CarsFenceExceptionDetailVo> getCarsFenceExceptionDetail(@RequestParam Integer fenceExceptionId) {
		ResponseResult<CarsFenceExceptionDetailVo> result = new ResponseResult<>();
		try {
			return result.success(carFenceExceptionBffService.getCarsFenceExceptionDetail(fenceExceptionId));
		} catch (Exception e) {
			logger.error("[getCarsFenceExceptionDetail]获取围栏异常的详细信息", e);
			result.error("获取围栏异常的详细信息异常"+e);
		}
		return result;
	}

	/**
	 * 车辆监控-车辆失联
	 * @param
	 * @return
	 */
	@Override
	@ApiOperation(value = "获取车辆失联列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "license", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "beginTime", value = "报警开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endTime", value = "报警结束时间  ", required = false, dataType = "String"),
			@ApiImplicitParam(name = "pageNum", value = "当前页", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "页大小", required = true, dataType = "Integer"),
	})
	@GetMapping(value = "/monitor/offlineAlarms/list")
	public ResponseResult<Paged<OfflineAlarmVo>> getOfflineAlarmVoList(@RequestParam Map<String, Object> params, Integer pageNum, Integer pageSize) {
		ResponseResult<Paged<OfflineAlarmVo>> result = new ResponseResult<>();
        logger.info("车辆管理-车辆监控-车辆失联入参:{},pageNum:{},pageSize:{}",params,pageNum,pageSize);
		try {
			return result.success(iVehicleMonitorBffService.getOfflineAlarmVoList(params,pageNum,pageSize));
		} catch (Exception e) {
			logger.error("[getOfflineAlarmVoList]获取车联失列表异常", e);
			result.error("获取车联失表异常"+e);
		}
		return result;
	}

	/**
	 * 车辆监控-异变列表
	 * @param
	 * @return
	 */
	@Override
	@ApiImplicitParams({
			@ApiImplicitParam(name = "license", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "beginTime", value = "报警开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endTime", value = "报警结束时间  ", required = false, dataType = "String"),
			@ApiImplicitParam(name = "pageNum", value = "当前页", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "页大小", required = true, dataType = "Integer"),
	})
	@ApiOperation(value = "获取里程异变列表")
	@GetMapping(value = "/monitor/mileageExAlarms/list")
	public ResponseResult<Paged<MileageExAlarmsVo>> getMileageExAlarmsList(@RequestParam Map<String, Object> params, @RequestParam Integer pageNum, @RequestParam Integer pageSize) {
        logger.info("车辆管理-车辆监控-里程异变入参:{},pageNum:{},pageSize:{}",params,pageNum,pageSize);
		ResponseResult<Paged<MileageExAlarmsVo>> result = new ResponseResult<>();
		try {
			return result.success(iVehicleMonitorBffService.getMileageExAlarmsList(params,pageNum,pageSize));
		} catch (Exception e) {
			logger.error("[mileageExAlarms]获取车联失列表异常", e);
			result.error("获取车联失列表异常"+e);
		}
		return result;
	}


	/**
	 * 围栏监控-驶出仓储报警/fence/exception/list
	 * @param
	 * @return
	 */
	@Override
	@ApiOperation(value = "驶出仓储报警")
	@GetMapping(value = "/monitor/warehouseAlarm/list")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "license", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "beginTime", value = "报警开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endTime", value = "报警结束时间  ", required = false, dataType = "String"),
			@ApiImplicitParam(name = "stockId", value = "中转库id ", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "pageNum", value = "当前页", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "页大小", required = true, dataType = "Integer"),
	})
	public ResponseResult<Paged<WarehouseAlarmVo>> getWarehouseAlarmList(@RequestParam Map<String, Object> params, Integer pageNum, Integer pageSize) {
        logger.info("车辆管理-车辆监控-驶出仓储报警入参:{},pageNum:{},pageSize:{}",params,pageNum,pageSize);
	    ResponseResult<Paged<WarehouseAlarmVo>> result = new ResponseResult<>();
		try {
			return result.success(iVehicleMonitorBffService.getWarehouseAlarmList(params,pageNum,pageSize));
		} catch (Exception e) {
			logger.error("[warehouseAlarm]获取驶出仓储报警列表异常", e);
			result.error("获取驶出仓储报警列表异常"+e);
		}
		return result;
	}

	@Override
	@ApiImplicitParams({
			@ApiImplicitParam(name = "license", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "beginTime", value = "报警开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endTime", value = "报警结束时间  ", required = false, dataType = "String"),
			@ApiImplicitParam(name = "stockId", value = "门店id ", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "dealerId", value = "经销商id  ", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "pageNum", value = "当前页", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "页大小", required = true, dataType = "Integer"),
	})
	@ApiOperation(value = "驶出门店报警")
	@GetMapping(value = "/monitor/storesAlarm/list")
	public ResponseResult<Paged<WarehouseAlarmVo>> getStoresAlarmList(@RequestParam Map<String, Object> params, Integer pageNum, Integer pageSize) {
        logger.info("车辆管理-车辆监控-驶出门店报警入参:{},pageNum:{},pageSize:{}",params,pageNum,pageSize);
	    ResponseResult<Paged<WarehouseAlarmVo>> result = new ResponseResult<>();
		try {
			return result.success(iVehicleMonitorBffService.getStoresAlarmList(params,pageNum,pageSize));
		} catch (Exception e) {
			logger.error("[warehouseAlarm]获取驶出仓储报警列表异常", e);
			result.error("获取驶出仓储报警列表异常"+e);
		}
		return result;
	}

	@ApiImplicitParams({
			@ApiImplicitParam(name = "license", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "beginTime", value = "报警开始时间", required = false, dataType = "String"),
			@ApiImplicitParam(name = "endTime", value = "报警结束时间  ", required = false, dataType = "String"),
			@ApiImplicitParam(name = "pageNum", value = "当前页", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "页大小", required = true, dataType = "Integer"),
	})
	@Override
	@ApiOperation(value ="驶入非法区域报警")
	@GetMapping(value = "/monitor/illegalAlarm/list")
	public ResponseResult<Paged<IllegalAlarmVo>> getIllegalAlarmList(@RequestParam Map<String, Object> params, Integer pageNum, Integer pageSize) {
        logger.info("车辆管理-车辆监控-驶入非法区域报警入参:{},pageNum:{},pageSize:{}",params,pageNum,pageSize);
	    ResponseResult<Paged<IllegalAlarmVo>> result = new ResponseResult<>();
		try {
			return result.success(iVehicleMonitorBffService.getIllegalAlarmList(params,pageNum,pageSize));
		} catch (Exception e) {
			logger.error("[warehouseAlarm]获取驶出仓储报警列表异常", e);
			result.error("获取驶出仓储报警列表异常"+e);
		}
		return result;
	}
	@ApiImplicitParams({
			@ApiImplicitParam(name = "operateType", value = "命令集合：4设为租赁、5设为非租赁、8开启动、9关闭动力", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
	})
	@Override
	@ApiOperation(value ="下发控车命令")
	@PostMapping(value = "/control/command")
	public ResponseResult sendControlCommand(@RequestBody Map<String, Object> params) {
		logger.info("车辆管理-下发控车命令-入参:{}",params);
		try {
			return iVehicleMonitorBffService.sendControlCommand(params);
		} catch (Exception e) {
			logger.error("[warehouseAlarm]获取驶出仓储报警列表异常", e);
		 return 	new  ResponseResult().error("下发控车命令失败");
		}

	}
	
		
	/**
	 * 违章标记接口
	 * @param modifyVo
	 * @return
	 */
	@Override
	@ApiOperation(value = "违章标记接口")
	@OptionalLogConfig(methods="标记已缴费或取消标记")
	@PostMapping(value = "/violation/modify")
	public ResponseResult<Boolean> modifyViolationStatusById(@RequestBody CarsViolationModifyVo modifyVo){
		ResponseResult<Boolean>  result = new ResponseResult<>();
		try {
			Boolean flag = violationBffService.modifyStatusById(modifyVo);
			if(!flag) {
				result.error("操作失败");
			}
			return result.success(flag);
		}catch (BizException e) {
			result.error(e.getExceptionCode(),e.getMessage());
		}catch (IllegalArgumentException e) {
			result.error(400,e.getMessage());
		}catch (Exception e) {
			logger.error("[modifyViolationStatusById]违章标记接口异常", e);
			result.error("违章标记接口异常");
		}
		return result;
	}
	
	/**
	 * 企业订单添加车辆检验接口
	 * @param vin
	 * @return
	 */
	@Override
	@ApiOperation(value = "企业订单添加车辆检验接口")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
		@ApiImplicitParam(name = "vehicleId", value = "车型id", required = true, dataType = "Integer")
    })
	@GetMapping(value = "/enterprise/verify")
	public ResponseResult<CarVo> getEnterpriseVerify(String vin,Integer vehicleId){
		ResponseResult<CarVo>  result = new ResponseResult<>();
		try {
			return result.success(carBffService.getCarByVin(vin,vehicleId));
		}catch (BizException e) {
			result.error(e.getExceptionCode(),e.getMessage());
		}catch (IllegalArgumentException e) {
			result.error(400,e.getMessage());
		}catch (Exception e) {
			logger.error("[getEnterpriseVerify]企业订单添加车辆检验接口异常", e);
			result.error("企业订单添加车辆检验接口异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "获取车辆里程")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String")
	})
	@GetMapping(value = "/odo/mileage")
	public ResponseResult<Integer> getCarOdoMileage(String vin) {
		ResponseResult<Integer>  result = new ResponseResult<>();
		try {
			return result.success(carBffService.getCarOdoMileage(vin));
		}catch (BizException e) {
			result.error(e.getExceptionCode(),e.getMessage());
		}catch (IllegalArgumentException e) {
			result.error(400,e.getMessage());
		}catch (Exception e) {
			logger.error("[getCarOdoMileage]获取车辆里程接口异常", e);
			result.error("获取车辆里程接口异常");
		}
		return result;
	}

	/**
	 * 获取配置列表
	 *
	 * @return
	 */
	@Override
	@ApiOperation(value = "获取预警参数信息")
	@GetMapping(value = "/warn/config/list")
	public ResponseResult<List<WarnConfigVo>> getWarnConfigList() {
		ResponseResult<List<WarnConfigVo>>  result = new ResponseResult<>();
		try {
			return result.success(warnConfigBffService.getWarnConfigList());
		}catch (BizException e) {
			result.error(e.getExceptionCode(),e.getMessage());
		}catch (Exception e) {
			logger.error("[getWarnConfigList]获取预警参数信息接口异常", e);
			result.error("获取预警参数信息接口异常");
		}
		return result;
	}

	/**
	 * 编辑配置
	 *
	 * @param list
	 * @return
	 */
	@Override
	@ApiOperation(value = "预警参数编辑")
	@OptionalLogConfig(methods="预警参数编辑")
	@PostMapping(value = "/warn/config/modify")
	public ResponseResult<Boolean> modifyWarnConfig(@RequestBody List<WarnConfigModifyVo> list) {
		ResponseResult<Boolean>  result = new ResponseResult<>();
		try {
			return result.success(warnConfigBffService.modifyWarnConfig(list));
		}catch (BizException e) {
			result.error(e.getExceptionCode(),e.getMessage());
		}catch (Exception e) {
			logger.error("[modifyWarnConfig]预警参数编辑接口异常", e);
			result.error("预警参数编辑接口异常");
		}
		return result;
	}


	@Override
	@ApiOperation(value = "获取保养预警列表信息")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "vehicleId", value = "车型id", required = false, dataType = "Integer"),
			@ApiImplicitParam(name = "sortName", value = "排序字段", required = false, dataType = "String"),
			@ApiImplicitParam(name = "sortWay", value = "排序方式 asc:正序，desc:倒叙", required = false, dataType = "String"),
			@ApiImplicitParam(name = "pageNum", value = "页码", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "Integer")
	})
	@GetMapping(value = "/maintenance/config/list")
	public ResponseResult<Paged<MaintenanceConfigVo>> getMaintenanceConfigPage(@RequestParam Map<String, Object> map,
																			   @RequestParam Integer pageNum,@RequestParam Integer pageSize) {

		ResponseResult<Paged<MaintenanceConfigVo>> result = new ResponseResult<>();
		try {
			return result.success(maintenanceBffService.getMaintenanceConfigPage(map, pageNum, pageSize));
		} catch (BizException e) {
			logger.error("[getMaintenanceConfigPage]获取保养预警列表信息异常", e);
			result.error(e.getMessage());
		} catch (Exception e) {
			logger.error("[getMaintenanceConfigPage]获取保养预警列表信息异常", e);
			result.error("获取保养预警列表信息异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "获取保养预警信息")
	@ApiImplicitParam(name = "id", value = "保养预警id", required = true, dataType = "Integer")
	@GetMapping(value = "/maintenance/config/detail")
	public ResponseResult<MaintenanceConfigVo> getMaintenanceConfig(@RequestParam Integer id) {
		ResponseResult<MaintenanceConfigVo> result = new ResponseResult<>();
		try {
			return result.success(maintenanceBffService.getMaintenanceConfig(id));
		} catch (BizException e) {
			logger.error("[getMaintenanceConfig]获取保养预警信息异常", e);
			result.error(e.getMessage());
		} catch (Exception e) {
			logger.error("[getMaintenanceConfig]获取保养预警信息异常", e);
			result.error("获取保养预警信息异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "添加保养预警")
	@PostMapping(value = "/maintenance/config/create")
	@OptionalLogConfig(methods = "添加保养预警")
	public ResponseResult<Boolean> createMaintenanceConfig(@RequestBody MaintenanceConfigCreateVo dto) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			return result.success(maintenanceBffService.createMaintenanceConfig(dto));
		} catch (BizException e) {
			logger.error("[createMaintenanceConfig]添加保养预警信息异常", e);
			result.error(e.getMessage());
		} catch (Exception e) {
			logger.error("[createMaintenanceConfig]添加保养预警信息异常", e);
			result.error("添加保养预警信息异常");
		}
		return result;
	}

	@Override
	@ApiOperation(value = "编辑保养预警信息")
	@PostMapping(value = "/maintenance/config/modify")
	@OptionalLogConfig(methods = "编辑保养预警")
	public ResponseResult<Boolean> modifyMaintenanceConfig(@RequestBody MaintenanceConfigModifyVo dto) {
		ResponseResult<Boolean> result = new ResponseResult<>();
		try {
			return result.success(maintenanceBffService.modifyMaintenanceConfig(dto));
		} catch (BizException e) {
			logger.error("[modifyMaintenanceConfig]编辑保养预警信息异常", e);
			result.error(e.getMessage());
		} catch (Exception e) {
			logger.error("[modifyMaintenanceConfig]编辑保养预警信息异常", e);
			result.error("编辑保养预警信息异常");
		}
		return result;
	}
	
	@ApiOperation(value = "车辆违章 获取根据车架号 获取车牌号信息")
	@ApiImplicitParam(name = "vin", value = "车架号", required = true, dataType = "String")
	@GetMapping(value = "/violation/car/detail")
	@Override
	public ResponseResult<CarVo> getCarByVin(@RequestParam String vin) {
		ResponseResult<CarVo> result = new ResponseResult<>();
		try {
			return result.success(carBffService.getCarByVin(vin));
		} catch (BizException e) {
			logger.error("[getCarByVin]车辆违章 获取根据车架号 获取车牌号信息异常", e);
			result.error(e.getMessage());
		} catch (Exception e) {
			logger.error("[getCarByVin]车辆违章 获取根据车架号 获取车牌号信息异常", e);
			result.error("车辆违章 获取根据车架号 获取车牌号信息异常");
		}
		return result;
	}

	
	@Override
	@ApiOperation(value = "获取车辆违章(根据车辆vin查询违章信息)")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "licencePlate", value = "车牌号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "vin", value = "车架号", required = false, dataType = "String"),
			@ApiImplicitParam(name = "pageNum", value = "页码", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "Integer")

	})
	@GetMapping(value = "/violation/query")
	public ResponseResult<Paged<CarsViolationVo>> getCarsViolationQueryPaged(@RequestParam Map<String, Object> params, @RequestParam Integer pageNum, @RequestParam Integer pageSize) {
		ResponseResult<Paged<CarsViolationVo>> result = new ResponseResult<>();
		try {
			result.success(violationBffService.getCarsViolationQueryPaged(params, pageNum, pageSize));
		} catch (Exception e) {
			// 记录异常，返回异常信息
			logger.error("[getCarsViolationQueryPaged]获取车辆违章(根据车辆vin查询违章信息)异常", e);
			result.error("获取车辆违章(根据车辆vin查询违章信息)异常:" + e.getMessage());
		}
		return result;
	}
}
